package com.szxx.domain;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.szxx.suit.AbstractAnalysisResult;
import com.szxx.suit.AbstractSuitType;
import com.szxx.util.PokerUtil;

/**
 * 牌列 <br>
 * 可以是手牌，也可以是玩家出的牌 <br>
 * 排列经过处理会填充牌型和权重属性 <br>
 * 
 * @author Ambrose
 */
public class Cards implements Comparable<Cards>, Iterable<Card>, Cloneable {

	private List<Card> cardList = new ArrayList<Card>();
	/** 根据对应牌型结果 */
	private AbstractAnalysisResult result;
	
	public Cards() {
	}
	
	public Cards(List<Card> cards) {
		if (cards != null) {
			this.cardList.addAll(cards);
		}
	}

	/**
	 * 添加一张牌
	 * 
	 * @param card
	 */
	public void addCard(Card card) {
		if (card != null) {
			this.cardList.add(card);
		}
	}

	/**
	 * 添加牌
	 * 
	 * @param card
	 */
	public void addCards(List<Card> cards) {
		if (cards != null) {
			this.cardList.addAll(cards);
		}
	}
	
	/**
	 * 添加牌
	 * 
	 * @param card
	 */
	public void addCards(Cards cards) {
		if (cards != null) {
			addCards(cards.cardList);
		}
	}
	
	/**
	 * 添加一张牌
	 * 
	 * @param card
	 */
	public Card get(int index) {
		return cardList.get(index);
	}
	
	/**
	 * 返回牌组长度
	 * 
	 * @return
	 */
	public int size() {
		return this.cardList.size();
	}
	
	@Override
	public int compareTo(Cards o) {
		if (o.result == null) {
			return 1;
		} else if (this.result == null) {
			return -1;
		} else {
			return this.result.compareTo(o.result);
		}
	}
	
	@Override
	public Iterator<Card> iterator() {
		return cardList.iterator();
	}
	
	/**
	 * 注意这里的cardList里的元素是浅克隆
	 */
	@Override
	public Cards clone() {
		Cards copy = null;
		try {
			copy = (Cards) super.clone();
			if (result != null) {
				copy.setResult(result.clone());
			}
			copy.setCardList(PokerUtil.copy(cardList));
		} catch (CloneNotSupportedException e) {
			copy = new Cards();
			if (result != null) {
				copy.setResult(result.clone());
			}
			copy.setCardList(PokerUtil.copy(cardList));
		}
		return copy;
	}
	
	/**
	 * 是否包含牌列
	 */
	public boolean containsAll(List<Card> cards) {
		if (cards == null || cards.size() == 0) {
			return true;
		} else {
			return cardList.containsAll(cards);
		}
	}
	
	/**
	 * 删除牌列
	 */
	public boolean removeAll(Cards cards) {
		if (cards == null || cards.size() == 0) {
			return true;
		} else {
			return cardList.removeAll(cards.cardList);
		}
	}
	
	/**
	 * 删除牌列
	 */
	public boolean removeAll(List<Card> cardList) {
		if (cardList == null || cardList.size() == 0) {
			return true;
		} else {
			return cardList.removeAll(cardList);
		}
	}
	
	/**
	 * 截取牌列
	 */
	public List<Card> subList(int fromIndex, int toIndex) {
		return cardList.subList(fromIndex, toIndex);
	}
	
	/**
	 * 清空
	 */
	public void clear() {
		cardList.clear();
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((cardList == null) ? 0 : cardList.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Cards other = (Cards) obj;
		if (cardList == null) {
			if (other.cardList != null)
				return false;
		} else if (!cardList.equals(other.cardList))
			return false;
		return true;
	}
	
	public static void main(String[] args) {
		Cards cards = new Cards();
		cards.addCard(new Card(CardShape.DIAMOND, 5));
		cards.addCard(new Card(CardShape.CLUB, 5));
		cards.addCard(new Card(CardShape.HEART, 6));
		Cards cards1 = new Cards();
		cards1.addCard(new Card(CardShape.DIAMOND, 5));
		cards1.addCard(new Card(CardShape.CLUB, 5));
		cards1.addCard(new Card(CardShape.HEART, 6));
		System.out.println(cards.equals(cards1));
	}

	@Override
	public String toString() {
		return "Cards [cardList=" + cardList + ", result=" + result + "]";
	}

	public List<Card> getCardList() {
		return cardList;
	}
	
	public void setCardList(List<Card> cardList) {
		this.cardList = cardList;
	}

	public AbstractSuitType getType() {
		return result.getType();
	}
	
	public AbstractAnalysisResult getResult() {
		return result;
	}

	public void setResult(AbstractAnalysisResult result) {
		this.result = result;
	}

}
